package com.hotely5d.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.hotely5d.dao.*;
import com.hotely5d.entity.*;
import com.hotely5d.entity.model.Result;
import com.hotely5d.entity.model.StatusCode;
import com.hotely5d.entity.query.RoomQuery;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Transactional
public class AppointmentService {

    @Autowired
    private AppointmentMapper appointmentMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private RoomService roomService;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private CategoryService categoryService;

    public List<Appointment> findAll() {
        // 只查询未删除的预约
        return appointmentMapper.selectList(new EntityWrapper<Appointment>().eq("deleted", 0));
    }

    public Page<Appointment> search(Page<Appointment> page, Appointment appointment) {
        List<Appointment> list = appointmentMapper.selectPage(page, getEntityWrapper(appointment));
        for (Appointment a : list) {
            Room room = roomService.findById(a.getRoomId());
            a.setRoom(room);
            Member member = memberMapper.selectById(a.getMemberId());
            a.setMember(member);
        }
        return page.setRecords(list);
    }

    public List<Appointment> search(Appointment appointment) {
        return appointmentMapper.selectList(getEntityWrapper(appointment));
    }

    //条件构造器
    private EntityWrapper<Appointment> getEntityWrapper(Appointment appointment) {
        EntityWrapper<Appointment> entityWrapper = new EntityWrapper<>();
        // 只查询未删除的预约
        entityWrapper.eq("deleted", 0);
        if (null != appointment) {
            if (!StringUtils.isEmpty(appointment.getRemark())) {
                entityWrapper.like("remark", String.valueOf(appointment.getRemark()));
            }
            if (!StringUtils.isEmpty(appointment.getMemberId())) {
                entityWrapper.eq("member_id", String.valueOf(appointment.getMemberId()));
            }
            if (!StringUtils.isEmpty(appointment.getStatus())) {
                entityWrapper.eq("status", String.valueOf(appointment.getStatus()));
            }
        }
        entityWrapper.orderBy("id",false);
        return entityWrapper;
    }

    public void modify(Appointment appointment) {
        appointmentMapper.updateById(appointment);
    }

    public Result add(Appointment appointment) {
        //判断是否有待确定的单
        Integer count = appointmentMapper.selectCount(new EntityWrapper<Appointment>()
                .eq("member_id", appointment.getMemberId())
                .eq("room_id", appointment.getRoomId())
                .eq("status", 1)
                .eq("deleted", 0));
        if(count != 0){
            return new Result(false, StatusCode.ERROR, "请勿重复预订！");
        }
        //判断是否已预约或者已入住这个房间
//        ArrayList<Integer> statusList = new ArrayList<>();
//        statusList.add(1);//已预订
//        statusList.add(2);//已入住
//        List<Orders> ordersList = ordersMapper.selectList(new EntityWrapper()
//                .eq("room_id", appointment.getRoomId())
//                .in("status", statusList));
//        if(ordersList.size() != 0){
//            return new Result(false, StatusCode.ERROR, "预订失败,房间已满！");
//        }
        //插入预约表
        Room r = roomService.findById(appointment.getRoomId());
        appointment.setMoney(r.getCategory().getPrice());
        appointment.setStatus(1);//1-待确认 2-预约成功 3-已取消
        // 设置默认值：未删除
        appointment.setDeleted(0);
        appointmentMapper.insert(appointment);
        return new Result(true, StatusCode.OK, "操作成功,等待酒店确认！");
    }

    public Appointment findById(Integer id) {
        // 只查询未删除的预约
        List<Appointment> appointments = appointmentMapper.selectList(new EntityWrapper<Appointment>().eq("id", id).eq("deleted", 0));
        return appointments.isEmpty() ? null : appointments.get(0);
    }

    public void removeById(Integer id) {
        // 实现逻辑删除：将deleted字段设置为1
        Appointment appointment = new Appointment();
        appointment.setId(id);
        appointment.setDeleted(1);
        appointmentMapper.updateById(appointment);
    }

    public List<Room> findRoomList(RoomQuery roomQuery) {
        EntityWrapper wrapper = new EntityWrapper();
        wrapper.eq("status",1);
        if(!StringUtils.isEmpty(roomQuery.getCategoryId())){
            wrapper.eq("category_id",roomQuery.getCategoryId());
        }
        List<Room> list = roomMapper.selectList(wrapper);
        for (Room r : list) {
            //查询房型
            Category category = categoryService.findById(r.getCategoryId());
            r.setCategory(category);
            //1.根据当前年月日和房间id判断是否入住，入住则不可预约和入住 2.根据当前年月日和房间id判断是否预约，预约成功则不可预约和入住
            ArrayList<Integer> statusList = new ArrayList<>();
            statusList.add(1);//已预订
            statusList.add(2);//已入住
            List<Orders> ordersList = ordersMapper.selectList(new EntityWrapper()
                    .eq("room_id", r.getId())
                    .in("status", statusList));
            if(ordersList.size() == 0){
                r.setCanUse(true);
                continue;
            }
            String startDate = DateFormatUtils.format(ordersList.get(0).getStartTime(),"yyyy-MM-dd");
            //不为0且当前日期!=入住日期，判断当前日期是否在入住日期+居住天数之后
            r.setCanUse(canAppointment(roomQuery.getStartDate(),startDate,ordersList.get(0).getDays()));
        }
        //过滤
        if(!StringUtils.isEmpty(roomQuery.getCanUse())){
            List<Room> rooms = list.stream().filter(f -> f.getCanUse() == roomQuery.getCanUse()).collect(Collectors.toList());
            return rooms;
        }
        return list;
    }

    //判断是否可预约
    public boolean canAppointment(String currentDate,String startDate,Integer days)  {
        List<String> dateList = new ArrayList();

        for (int i = 0; i < days ; i++) {
            try {
                Date date = DateUtils.parseDate(startDate, "yyyy-MM-dd");
                Date rs = DateUtils.addDays(date, i);
                dateList.add(DateFormatUtils.format(rs,"yyyy-MM-dd"));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        return !dateList.contains(currentDate);
    }

    public Result confirm(Integer appointmentId) {
        Appointment appointment = appointmentMapper.selectById(appointmentId);
        //判断是否有入住但是没退房或者有预订但是没入住
        ArrayList<Integer> statusList = new ArrayList<>();
        statusList.add(1);//已预订
        statusList.add(2);//已入住
        List<Orders> ordersList = ordersMapper.selectList(new EntityWrapper()
                .eq("room_id", appointment.getRoomId())
                .in("status", statusList));
        if(ordersList.size() > 0){
            return new Result(false, StatusCode.ERROR,"该房间已被占用，请取消预约或者前往【入住管理】退房！");
        }
        //修改预订状态，预订成功
        appointment.setStatus(2);
        appointmentMapper.updateById(appointment);
        //生成入住订单，状态为已预订
        Orders order = new Orders();
        order.setMemberId(appointment.getMemberId());
        order.setRoomId(appointment.getRoomId());
        order.setDays(appointment.getDays());
        order.setStartTime(appointment.getStartTime());
        order.setMoney(appointment.getMoney());
        order.setStatus(1);
        ordersMapper.insert(order);
        return new Result(true, StatusCode.OK,"操作成功！");
    }

    /**
     * 导出预约数据到Excel
     * @param appointment 查询条件
     * @param response HTTP响应
     * @throws IOException IO异常
     */
    public void exportAppointmentData(Appointment appointment, HttpServletResponse response) throws IOException {
        // 查询预约数据并填充关联信息
        List<Appointment> appointmentList = appointmentMapper.selectList(getEntityWrapper(appointment));

        // 填充关联的Member和Room信息
        for (Appointment a : appointmentList) {
            Room room = roomService.findById(a.getRoomId());
            a.setRoom(room);
            Member member = memberMapper.selectById(a.getMemberId());
            a.setMember(member);
        }

        // 创建工作簿
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("预约信息");

        // 创建标题行样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setBorderTop(BorderStyle.MEDIUM);
        headerStyle.setBorderBottom(BorderStyle.MEDIUM);
        headerStyle.setBorderLeft(BorderStyle.MEDIUM);
        headerStyle.setBorderRight(BorderStyle.MEDIUM);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        Font headerFont = workbook.createFont();
        headerFont.setColor(IndexedColors.WHITE.getIndex());
        headerFont.setBold(true);
        headerFont.setFontHeightInPoints((short) 12);
        headerStyle.setFont(headerFont);

        // 创建数据行样式
        CellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setBorderTop(BorderStyle.THIN);
        dataStyle.setBorderBottom(BorderStyle.THIN);
        dataStyle.setBorderLeft(BorderStyle.THIN);
        dataStyle.setBorderRight(BorderStyle.THIN);
        dataStyle.setAlignment(HorizontalAlignment.CENTER);
        dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        // 创建左对齐样式（用于文本）
        CellStyle leftAlignStyle = workbook.createCellStyle();
        leftAlignStyle.cloneStyleFrom(dataStyle);
        leftAlignStyle.setAlignment(HorizontalAlignment.LEFT);

        // 创建右对齐样式（用于金额）
        CellStyle rightAlignStyle = workbook.createCellStyle();
        rightAlignStyle.cloneStyleFrom(dataStyle);
        rightAlignStyle.setAlignment(HorizontalAlignment.RIGHT);

        // 创建标题行
        Row headerRow = sheet.createRow(0);
        headerRow.setHeight((short) 500);

        String[] headers = {"预约ID", "用户姓名", "用户电话", "身份证号", "性别", "房型", "房号", "入住时间", "居住天数", "预约状态", "备注", "已付金额"};

        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
        }

        // 填充数据
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        int rowIndex = 1;

        for (Appointment appointmentData : appointmentList) {
            Row row = sheet.createRow(rowIndex++);
            row.setHeight((short) 400);

            // 预约ID
            Cell cell0 = row.createCell(0);
            cell0.setCellValue(appointmentData.getId());
            cell0.setCellStyle(dataStyle);

            // 用户姓名
            Cell cell1 = row.createCell(1);
            cell1.setCellValue(appointmentData.getMember() != null ? appointmentData.getMember().getName() : "");
            cell1.setCellStyle(leftAlignStyle);

            // 用户电话
            Cell cell2 = row.createCell(2);
            cell2.setCellValue(appointmentData.getMember() != null ? appointmentData.getMember().getPhone() : "");
            cell2.setCellStyle(dataStyle);

            // 身份证号
            Cell cell3 = row.createCell(3);
            cell3.setCellValue(appointmentData.getMember() != null ? appointmentData.getMember().getIdcard() : "");
            cell3.setCellStyle(dataStyle);

            // 性别
            Cell cell4 = row.createCell(4);
            String genderText = "";
            if (appointmentData.getMember() != null && appointmentData.getMember().getGender() != null) {
                genderText = appointmentData.getMember().getGender() == 1 ? "男" : "女";
            }
            cell4.setCellValue(genderText);
            cell4.setCellStyle(dataStyle);

            // 房型
            Cell cell5 = row.createCell(5);
            String categoryName = "";
            if (appointmentData.getRoom() != null && appointmentData.getRoom().getCategory() != null) {
                categoryName = appointmentData.getRoom().getCategory().getCategoryName();
            }
            cell5.setCellValue(categoryName);
            cell5.setCellStyle(leftAlignStyle);

            // 房号
            Cell cell6 = row.createCell(6);
            String roomNum = "";
            if (appointmentData.getRoom() != null && appointmentData.getRoom().getRoomNum() != null) {
                roomNum = String.valueOf(appointmentData.getRoom().getRoomNum());
            }
            cell6.setCellValue(roomNum);
            cell6.setCellStyle(dataStyle);

            // 入住时间
            Cell cell7 = row.createCell(7);
            String startTimeStr = "";
            if (appointmentData.getStartTime() != null) {
                startTimeStr = dateFormat.format(appointmentData.getStartTime());
            }
            cell7.setCellValue(startTimeStr);
            cell7.setCellStyle(dataStyle);

            // 居住天数
            Cell cell8 = row.createCell(8);
            cell8.setCellValue(appointmentData.getDays() != null ? appointmentData.getDays() : 0);
            cell8.setCellStyle(dataStyle);

            // 预约状态
            Cell cell9 = row.createCell(9);
            String statusText = "";
            if (appointmentData.getStatus() != null) {
                switch (appointmentData.getStatus()) {
                    case 1: statusText = "待确认"; break;
                    case 2: statusText = "预订成功"; break;
                    case 3: statusText = "预订失败"; break;
                    default: statusText = "未知"; break;
                }
            }
            cell9.setCellValue(statusText);
            cell9.setCellStyle(dataStyle);

            // 备注
            Cell cell10 = row.createCell(10);
            cell10.setCellValue(appointmentData.getRemark() != null ? appointmentData.getRemark() : "");
            cell10.setCellStyle(leftAlignStyle);

            // 已付金额
            Cell cell11 = row.createCell(11);
            double totalMoney = 0;
            if (appointmentData.getMoney() != null && appointmentData.getDays() != null) {
                totalMoney = appointmentData.getMoney().doubleValue() * appointmentData.getDays();
            }
            cell11.setCellValue("￥" + String.format("%.2f", totalMoney));
            cell11.setCellStyle(rightAlignStyle);
        }

        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
            // 设置最小列宽
            int currentWidth = sheet.getColumnWidth(i);
            if (currentWidth < 3000) {
                sheet.setColumnWidth(i, 3000);
            }
            // 设置最大列宽
            if (currentWidth > 8000) {
                sheet.setColumnWidth(i, 8000);
            }
        }

        // 冻结标题行
        sheet.createFreezePane(0, 1);

        // 设置响应头
        String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String fileName = "预约信息_" + timestamp + ".xlsx";

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        response.setCharacterEncoding("UTF-8");

        // 写入响应
        workbook.write(response.getOutputStream());
        workbook.close();
    }
}
